package cn.caplike.demo.rabbitmq.springboot.idempotence_reliability.application;

import cn.caplike.demo.rabbitmq.springboot.idempotence_reliability.domain.model.MessageDeliveryLog;
import cn.caplike.demo.rabbitmq.springboot.idempotence_reliability.port.adapter.persistence.mybatis.MessageDeliveryLogRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

/**
 * Description: 消息投递记录服务
 *
 * @author LiKe
 * @version 1.0.0
 * @date 2020-09-01 17:19
 */
@Service
public class MessageDeliveryLogService {

    private MessageDeliveryLogRepository repository;

    /**
     * Description: 更新记录状态为 "消费成功"
     *
     * @param messageId 消息 ID
     * @return boolean 成功与否
     * @author LiKe
     * @date 2020-09-02 20:33:20
     */
    public boolean consumedSuccess(String messageId) {
        final int updateCount = repository.updateStatus(messageId, MessageDeliveryLog.Status.CONSUMED_SUCCESS);
        return updateCount == 1;
    }

    /**
     * Description: 更新记录状态为 "投递成功"
     *
     * @param messageId 消息 ID
     * @return boolean 成功与否
     * @author LiKe
     * @date 2020-09-02 20:35:30
     */
    public boolean deliverySuccess(String messageId) {
        final int updateCount = repository.updateStatus(messageId, MessageDeliveryLog.Status.DELIVER_SUCCESS);
        return updateCount == 1;
    }

    /**
     * Description: 更新记录状态为 "投递成功"
     *
     * @param messageId 消息 ID
     * @return boolean 成功与否
     * @author LiKe
     * @date 2020-09-02 20:35:30
     */
    public boolean deliveryFailed(String messageId) {
        final int updateCount = repository.updateStatus(messageId, MessageDeliveryLog.Status.DELIVER_FAIL);
        return updateCount == 1;
    }

    /**
     * Description: 获得一条消息投递记录
     *
     * @param messageId 消息 ID
     * @return cn.caplike.demo.rabbitmq.springboot.idempotence.domain.model.MessageDeliveryLog
     * @author LiKe
     * @date 2020-09-02 14:36:19
     */
    public MessageDeliveryLog get(String messageId) {
        return repository.get(messageId);
    }

    /**
     * Description: 插入一条消息投递记录
     *
     * @param messageDeliveryLog {@link MessageDeliveryLog}
     * @return 插入条数
     * @author LiKe
     * @date 2020-09-02 14:36:00
     */
    public int add(MessageDeliveryLog messageDeliveryLog) {
        return repository.insert(messageDeliveryLog);
    }

    /**
     * Description: 抓取投递失败的记录
     *
     * @return java.util.List<cn.caplike.demo.rabbitmq.springboot.idempotence.domain.model.MessageDeliveryLog>
     * @author LiKe
     * @date 2020-09-03 09:54:27
     */
    public List<MessageDeliveryLog> fetchDeliveryFailed() {
        return repository.selectDeliveryFailed();
    }

    //    /**
//     * Description: 更新重试次数
//     *
//     * @return messageId 消息 ID
//     * @author LiKe
//     * @date 2020-09-03 10:31:07
//     */
//    public int increaseRetryCountByOne(String messageId) {
//        return repository.increaseRetryCount(1);
//    }
    public int updateResendingStatus(String messageId) {
        final MessageDeliveryLog messageDeliveryLog =
                Optional.ofNullable(repository.get(messageId)).orElseThrow(() -> new RuntimeException(String.format("Producer :: 无此记录 (messageId: %s)", messageId)));
        return messageDeliveryLog.resend();
    }

    // ~ Autowired
    // -----------------------------------------------------------------------------------------------------------------

    @Autowired
    public void setRepository(MessageDeliveryLogRepository repository) {
        this.repository = repository;
    }

}
